package com.myutil.qiniu;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.qiniu.common.Constants;
import com.qiniu.http.Client;
import com.qiniu.http.Response;
import com.qiniu.util.Auth;
import com.qiniu.util.Json;
import com.qiniu.util.StringMap;

/**
 * 该类主要提供CDN相关功能的接口实现，包括文件和目录的刷新，文件的预取，获取CDN访问日志链接，生成七牛时间戳防盗链等功能。
 * 参考文档：<a href="https://developer.qiniu.com/fusion">融合CDN</a>
 */
public final class SSLManager {
    private final Auth auth;
    private final String server;
    private final Client client;

    /*
     * SslManager 使用七牛标准的管理鉴权方式
     *
     * @param auth - Auth 对象
     * */
    public SSLManager(Auth auth) {
        //this(auth, "http://fusion.qiniuapi.com");
    	this(auth, "http://api.qiniu.com");
    }

    private SSLManager(Auth auth, String server) {
        this.auth = auth;
        this.server = server;
        this.client = new Client();
    }

    public SSLManager(Auth auth, String server, Client client) {
        this.auth = auth;
        this.server = server;
        this.client = client;
    }
    
	/*
	上传证书    POST /sslcert
	Content-Type: application/json
	Authorization: QBox <AccessToken>
	{
			"name": <Name>,
			"common_name": <CommonName>,
			"pri": <Pri>,
			"ca": <Ca>
	}
	
	response:
	{
		"certID": <CertID>
	}

	*/
    public String uploadSSLCert(String name,String common_name,String pri,String ca)  {
		JSONObject req = new JSONObject();
		String date=  new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date());
		
		req.put("name", name+" "+date);// 证书备注名
		req.put("common_name", common_name);//证书通用名称
		req.put("pri", pri);//私钥
		req.put("ca", ca);//证书pem
		JSONObject ret = uploadSSLCert(req);
		
		return ret.getString("certID");
    }
    
    public JSONObject uploadSSLCert(JSONObject req)  {
    	try {
        //HashMap<String, String[]> req = new HashMap<>();
        byte[] body = Json.encode(req).getBytes(Constants.UTF_8);
		
        String url = server + "/sslcert";
        @SuppressWarnings("deprecation")
		StringMap headers = auth.authorizationV2(url, "POST", body, Client.JsonMime);
        Response response = client.post(url, body, headers, Client.JsonMime);
        
        JSONObject ret = new JSONObject();
        ret.putAll(response.jsonToMap().map());
        
        return ret;
        
    	}catch(Exception ex) {
		   throw new RuntimeException(ex);
	   }
    }
    
    
    // return {}
    public JSONObject deleteSSLCert(String certId) {
    	try {
        //HashMap<String, String[]> req = new HashMap<>();
        String url = server + "/sslcert/"+certId;
        @SuppressWarnings("deprecation")
		StringMap headers = auth.authorizationV2(url, "DELETE", null, Client.JsonMime);
        Response response = client.delete(url, null, headers, Client.JsonMime);
        
        JSONObject ret = new JSONObject();
        ret.putAll(response.jsonToMap().map());
        return ret;
        
    	}catch(Exception ex) {
		   throw new RuntimeException(ex);
	   }
    }
    
    /**
     response:
     {
		"name": <Name>,
    	"common_name": <CommonName>,
        "dnsnames": <DNSNames>,  
    	"not_before": <NotBefore>,
     	"not_after": <NotAfter>,
		"pri": <Pri>,
		"ca": <Ca>,
	    "create_time": <CreateTime>
	}

     */
    public JSONObject getSSLCert(String certId) {
    	try {
    		
        //HashMap<String, String[]> req = new HashMap<>();
        String url = server + "/sslcert/"+certId;
        @SuppressWarnings("deprecation")
		StringMap headers = auth.authorizationV2(url, "GET", null, Client.FormMime);
        Response response = client.get(url, headers);
        
        JSONObject ret = new JSONObject();
        ret.putAll(response.jsonToMap().map());
        return ret;
        
    	}catch(Exception ex) {
		   throw new RuntimeException(ex);
	   }
    }
    
    
    /*
    
    marker 用于标示从哪个位置开始获取证书列表。不填或空表示从头开始
	Limit	int	返回的最大证书个数。默认 100

    response:
    {
		"name": <Name>,
   	"common_name": <CommonName>,
       "dnsnames": <DNSNames>,  
   	"not_before": <NotBefore>,
    	"not_after": <NotAfter>,
		"pri": <Pri>,
		"ca": <Ca>,
	    "create_time": <CreateTime>
	}

    */

    static public Date parseSecondTimestampToDate(Long secondTimeStamp) {
    	Date date = new Date(secondTimeStamp*1000);
    	return date;
    }
    
    static public String formatSecondTimestamp(Long secondTimestamp){//只含有秒
		String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(parseSecondTimestampToDate(secondTimestamp));
		return dateStr;
	}
    
    //获取最新的证书根据证书名称
	public JSONObject getLatestSSLCertByCertName(String sslCertName) {
		JSONObject latestCert = null;
		
		JSONArray certs = getSSLCertList();
		for (int i = 0; i < certs.size(); i++) {
			JSONObject cert = certs.getJSONObject(i);
			String commonName = cert.getString("common_name"); // "*.xiaoyung.com"
			Date notAfter = parseSecondTimestampToDate(cert.getLong("not_after"));// 存储的是秒 不是毫秒 //not_after: 1767016859
			//String certid = cert.getString("certid");//"68dc28b32e30940142284bdc"

			if(sslCertName.equals(commonName)) {
				Date latestCertNotAfter = latestCert==null?null:parseSecondTimestampToDate(latestCert.getLong("not_after"));

				if(latestCert==null ||  notAfter.getTime() >   latestCertNotAfter.getTime()) {

					latestCert = cert;
				}
			}
		}
		
		//过期时间
		String notAfterStr = formatSecondTimestamp(latestCert.getLong("not_after"));
		Long exprireDayCount = (latestCert.getLong("not_after")*1000 - new Date().getTime())/1000/3600/24;
		System.out.println("查询最新证书"+sslCertName+"("+exprireDayCount+"天后过期 "+" 过期时间:"+notAfterStr+"  证书: "+latestCert);
		return latestCert;
	}
	
	public JSONArray getSSLCertList() {
		return getSSLCertList(null,null);
	}
   public JSONArray getSSLCertList(String marker,Integer limit)  {
	   try {
		   
	   
       //HashMap<String, String[]> req = new HashMap<>();
       String url = server + "/sslcert?marker="+(StringUtils.isEmpty(marker)?"":marker)+"&limit="+(limit==null?"":limit);
       @SuppressWarnings("deprecation")
		StringMap headers = auth.authorizationV2(url, "GET", null, Client.FormMime);
       Response response = client.get(url, headers);
       
       JSONObject ret = new JSONObject();
       ret.putAll(response.jsonToMap().map());
       
       JSONArray certs = ret.getJSONArray("certs");
       
       System.out.println("获取证书列表: "+JSON.toJSONString(certs));
       return certs;
	   }catch(Exception ex) {
		   throw new RuntimeException(ex);
	   }
   }
   
   /*
    PUT /domain/<Name>/httpsconf
   Content-Type: application/json
   Authorization: QBox <AccessToken>
   {
   	"certId": <CertID>,
   	"forceHttps": <ForceHttps>,
   	"http2Enable": <Http2Enable>
   }
   
   response: {}

    */
   public JSONObject domainHttpsConf(String domainName,String certId,Boolean forceHttps,Boolean http2Enable) {
   	try {
       //HashMap<String, String[]> req = new HashMap<>();
       String url = server + "/domain/"+domainName+"/httpsconf";
       
       JSONObject req = new JSONObject();
		req.put("certId", certId);
		req.put("forceHttps", forceHttps);
		req.put("http2Enable",http2Enable);//

		byte[] body = Json.encode(req).getBytes(Constants.UTF_8);

       @SuppressWarnings("deprecation")
		StringMap headers = auth.authorizationV2(url, "PUT", body, Client.JsonMime);
       Response response = client.put(url, body, headers, Client.JsonMime);
       
       JSONObject ret = new JSONObject();
       ret.putAll(response.jsonToMap().map());
       return ret;
   		}catch(Exception ex) {
		   throw new RuntimeException(ex);
	   }
   }


  
}
